package com.jiangjiang.eshop.wms.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jiangjiang.eshop.finance.service.FinanceFacadeService;
import com.jiangjiang.eshop.order.service.OrderService;
import com.jiangjiang.eshop.wms.constant.SaleDeliveryOrderApproveResult;
import com.jiangjiang.eshop.wms.constant.SaleDeliveryOrderStatus;
import com.jiangjiang.eshop.wms.convert.SaleDeliveryOrderConvert;
import com.jiangjiang.eshop.wms.dao.SaleDeliveryOrderMapper;
import com.jiangjiang.eshop.wms.domain.SaleDeliveryOrderEntity;
import com.jiangjiang.eshop.wms.dto.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author Jianghaowen
 * @Date 2021/9/17
 * @Description: TODO
 * @Version V1.0
 **/
@Service
public class SaleDeliveryOrderService extends ServiceImpl<SaleDeliveryOrderMapper, SaleDeliveryOrderEntity> {


    @Autowired
    private SaleDeliveryOrderConvert saleDeliveryOrderConvert;
    @Autowired
    private SaleDeliveryOrderItemService saleDeliveryOrderItemService;
    @Autowired
    private SendOutOrderService sendOutOrderService;
    @Autowired
    private LogisticOrderService logisticOrderService;
    @Autowired
    private FinanceFacadeService financeFacadeService;
    @Autowired
    private OrderService orderService;

    /**
     * 分页查询销售出库数据
     *
     * @param query 查询条件
     * @return 分页查询结果
     */
    public Page<SaleDeliveryOrderDTO> queryForPage(SaleDeliveryOrderQuery query) {
        Page<SaleDeliveryOrderEntity> page = new Page<>(query.getPageNo(), query.getPageSize(), true);
        LambdaQueryWrapper<SaleDeliveryOrderEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(query.getStatus() != null, SaleDeliveryOrderEntity::getStatus, query.getStatus());
        return saleDeliveryOrderConvert.convertPage2DTO(this.getBaseMapper().selectPage(page, wrapper));
    }


    /**
     * 保存销售出库单数据
     *
     * @param deliveryOrderDTO 销售出库单数据
     * @return 处理结果
     */
    public Boolean saveSaleDeliveryOrder(SaleDeliveryOrderDTO deliveryOrderDTO) {
        // 保存销售出库单数据
        SaleDeliveryOrderEntity entity = saleDeliveryOrderConvert.convertDTO2Entity(deliveryOrderDTO);
        this.save(entity);
        deliveryOrderDTO.setId(entity.getId());

        // 销售出库单条目数据
        List<SaleDeliveryOrderItemDTO> itemDTOList = deliveryOrderDTO.getSaleDeliveryOrderItems()
                .stream()
                .peek(item -> item.setSaleDeliveryOrderId(entity.getId()))
                .collect(Collectors.toList());
        saleDeliveryOrderItemService.saveBatch(itemDTOList);

        // 保存发货单数据
        SendOutOrderDTO sendOutOrderDTO = deliveryOrderDTO.getSendOutOrderDTO();
        sendOutOrderDTO.setSaleDeliveryOrderId(entity.getId());
        sendOutOrderService.save(sendOutOrderDTO);

        // 保存物流单数据
        LogisticOrderDTO logisticOrderDTO = deliveryOrderDTO.getLogisticOrderDTO();
        logisticOrderDTO.setSaleDeliveryOrderId(entity.getId());
        logisticOrderService.save(logisticOrderDTO);
        return true;
    }

    /**
     * 根据订单id查询销售出库单数据
     *
     * @param orderId 销售出库单id
     * @return 查询结果
     */
    public SaleDeliveryOrderDTO queryByOrderId(Long orderId) {
        LambdaQueryWrapper<SaleDeliveryOrderEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(SaleDeliveryOrderEntity::getOrderId, orderId);
        SaleDeliveryOrderDTO saleDeliveryOrderDTO = saleDeliveryOrderConvert.convert2DTO(this.getOne(wrapper));
        setOtherFieldData(saleDeliveryOrderDTO);
        return saleDeliveryOrderDTO;
    }

    /**
     * 根据销售出库单id查询销售出库单全量数据
     *
     * @param id 销售出库单id
     * @return 查询结果
     */
    public SaleDeliveryOrderDTO queryById(Long id) {
        SaleDeliveryOrderDTO saleDeliveryOrder = saleDeliveryOrderConvert.convert2DTO(this.getById(id));
        setOtherFieldData(saleDeliveryOrder);
        return saleDeliveryOrder;
    }

    public void setOtherFieldData(SaleDeliveryOrderDTO saleDeliveryOrder){
        // 补充明细数据
        saleDeliveryOrder.setSaleDeliveryOrderItems(saleDeliveryOrderItemService.queryBySaleDeliveryOrderId(saleDeliveryOrder.getId()));
        // 补充发货单数据
        saleDeliveryOrder.setSendOutOrderDTO(sendOutOrderService.queryBySaleDeliveryOrderId(saleDeliveryOrder.getId()));
        // 补充物流单数据
        saleDeliveryOrder.setLogisticOrderDTO(logisticOrderService.queryBySaleDeliveryOrderId(saleDeliveryOrder.getId()));
    }

    /**
     * 更新销售出库单发货时间
     *
     * @param id           销售出库单id
     * @param deliveryTime 发货时间
     * @return
     */
    public Boolean updateDeliveryTime(Long id, Date deliveryTime) {
        LambdaUpdateWrapper<SaleDeliveryOrderEntity> wrapper = Wrappers.lambdaUpdate();
        wrapper.eq(SaleDeliveryOrderEntity::getId, id)
                .set(SaleDeliveryOrderEntity::getDeliveryTime, deliveryTime);
        return this.update(wrapper);
    }


    /**
     * 对销售出库单提交审核
     *
     * @param id 销售出库单id
     * @return 处理结果
     */
    public Boolean submitApprove(Long id) {
        return updateSaleDeliveryOrderStatus(id, SaleDeliveryOrderStatus.WAIT_FOR_APPROVE);
    }


    /**
     * 对销售出库单提交审核
     *
     * @param id 销售出库单id
     * @return 处理结果
     */
    public Boolean approve(Long id, Integer approveResult) {
        if (SaleDeliveryOrderApproveResult.REJECTED.equals(approveResult)) {
            return updateSaleDeliveryOrderStatus(id, SaleDeliveryOrderStatus.EDITING);
        }
        updateSaleDeliveryOrderStatus(id, SaleDeliveryOrderStatus.FINISHED);
        SaleDeliveryOrderDTO saleDeliveryOrder = queryById(id);
        // 通知财务中心，给物流公司打款
        financeFacadeService.payForLogisticsCompany(saleDeliveryOrder);
        //通知订单中心，“商品完成发货”事件发生了
        orderService.informGoodsDeliveryFinishedEvent(saleDeliveryOrder.getOrderId());
        return true;
    }

    /**
     * 更新销售出库单状态
     *
     * @return 处理结果
     */
    public Boolean updateSaleDeliveryOrderStatus(Long saleDeliveryOrderId, Integer status) {
        LambdaUpdateWrapper<SaleDeliveryOrderEntity> wrapper = Wrappers.lambdaUpdate();
        wrapper.eq(SaleDeliveryOrderEntity::getId, saleDeliveryOrderId)
                .set(SaleDeliveryOrderEntity::getStatus, status);
        return this.update(wrapper);
    }
}
